package org.dromara.ai.service;

import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.dromara.ai.domain.dto.AiChatRequest;
import org.dromara.ai.domain.dto.AiChatResponse;
import org.dromara.ai.provider.AiProvider;
import org.dromara.ai.provider.AiProviderManager;
import org.dromara.knowledge.domain.vo.KnowledgeSearchResultVo;
import org.dromara.knowledge.service.KnowledgeVectorService;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.stream.Collectors;

/**
 * AI聊天服务
 * 提供统一的AI聊天接口，支持同步、异步和流式对话模式
 *
 * @author RuoYi
 * @since 2024-01-01
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class AiChatService {

    private final AiProviderManager providerManager;
    private final KnowledgeVectorService knowledgeVectorService;

    /**
     * 同步聊天对话
     *
     * @param request 聊天请求
     * @return 聊天响应
     */
    public AiChatResponse chat(AiChatRequest request) {
        log.info("开始AI聊天对话 - 用户: {}, 模型: {}", request.getUserId(), request.getModel());
        
        try {
            // 预处理请求
            preprocessRequest(request);
            
            // 知识库增强
            if (Boolean.TRUE.equals(request.getEnableKnowledge()) && StringUtils.hasText(request.getKnowledgeId())) {
                enhanceWithKnowledge(request);
            }
            
            // 执行聊天
            AiChatResponse response = providerManager.chat(request);
            
            // 后处理响应
            postprocessResponse(response, request);
            
            log.info("AI聊天对话完成 - 用户: {}, 响应时间: {}ms", 
                request.getUserId(), response.getResponseTime());
            
            return response;
            
        } catch (Exception e) {
            log.error("AI聊天对话失败 - 用户: {}", request.getUserId(), e);
            return createErrorResponse(e, request);
        }
    }

    /**
     * 异步聊天对话
     *
     * @param request 聊天请求
     * @return 异步聊天响应
     */
    public CompletableFuture<AiChatResponse> chatAsync(AiChatRequest request) {
        log.info("开始异步AI聊天对话 - 用户: {}, 模型: {}", request.getUserId(), request.getModel());
        
        return CompletableFuture.supplyAsync(() -> {
            try {
                // 预处理请求
                preprocessRequest(request);
                
                // 知识库增强
                if (Boolean.TRUE.equals(request.getEnableKnowledge()) && StringUtils.hasText(request.getKnowledgeId())) {
                    enhanceWithKnowledge(request);
                }
                
                return request;
                
            } catch (Exception e) {
                log.error("异步AI聊天预处理失败 - 用户: {}", request.getUserId(), e);
                throw new RuntimeException(e);
            }
        }).thenCompose(preprocessedRequest -> {
            return providerManager.chatAsync(preprocessedRequest)
                .thenApply(response -> {
                    // 后处理响应
                    postprocessResponse(response, preprocessedRequest);
                    
                    log.info("异步AI聊天对话完成 - 用户: {}, 响应时间: {}ms", 
                        preprocessedRequest.getUserId(), response.getResponseTime());
                    
                    return response;
                });
        }).exceptionally(throwable -> {
            log.error("异步AI聊天对话失败 - 用户: {}", request.getUserId(), throwable);
            return createErrorResponse(throwable, request);
        });
    }

    /**
     * 流式聊天对话
     *
     * @param request 聊天请求
     * @param callback 流式回调
     */
    public void chatStream(AiChatRequest request, StreamCallback callback) {
        log.info("开始流式AI聊天对话 - 用户: {}, 模型: {}", request.getUserId(), request.getModel());
        
        try {
            // 预处理请求
            preprocessRequest(request);
            
            // 知识库增强
            if (Boolean.TRUE.equals(request.getEnableKnowledge()) && StringUtils.hasText(request.getKnowledgeId())) {
                enhanceWithKnowledge(request);
            }
            
            // 执行流式聊天
            providerManager.chatStream(request, new AiProvider.StreamCallback() {
                @Override
                public void onChunk(String chunk) {
                    callback.onChunk(chunk);
                }
                
                @Override
                public void onComplete(AiChatResponse response) {
                    // 后处理响应
                    postprocessResponse(response, request);
                    
                    log.info("流式AI聊天对话完成 - 用户: {}, 响应时间: {}ms", 
                        request.getUserId(), response.getResponseTime());
                    
                    callback.onComplete(response);
                }
                
                @Override
                public void onError(Throwable error) {
                    log.error("流式AI聊天对话失败 - 用户: {}", request.getUserId(), error);
                    callback.onError(error);
                }
            });
            
        } catch (Exception e) {
            log.error("流式AI聊天对话启动失败 - 用户: {}", request.getUserId(), e);
            callback.onError(e);
        }
    }

    /**
     * 批量聊天对话
     *
     * @param requests 聊天请求列表
     * @return 聊天响应列表
     */
    public List<CompletableFuture<AiChatResponse>> chatBatch(List<AiChatRequest> requests) {
        log.info("开始批量AI聊天对话 - 请求数量: {}", requests.size());
        
        return requests.stream()
            .map(this::chatAsync)
            .collect(Collectors.toList());
    }

    /**
     * 等待所有批量聊天完成
     *
     * @param futures 异步响应列表
     * @return 聊天响应列表
     */
    public List<AiChatResponse> waitForBatchCompletion(List<CompletableFuture<AiChatResponse>> futures) {
        CompletableFuture<Void> allOf = CompletableFuture.allOf(
            futures.toArray(new CompletableFuture[0])
        );
        
        return allOf.thenApply(v -> 
            futures.stream()
                .map(CompletableFuture::join)
                .collect(Collectors.toList())
        ).join();
    }

    /**
     * 预处理请求
     *
     * @param request 聊天请求
     */
    private void preprocessRequest(AiChatRequest request) {
        // 设置默认值
        if (request.getTemperature() == null) {
            request.setTemperature(0.7);
        }
        if (request.getMaxTokens() == null) {
            request.setMaxTokens(2000);
        }
        if (request.getStream() == null) {
            request.setStream(false);
        }
        
        // 验证请求参数
        validateRequest(request);
        
        // 记录请求日志
        log.debug("预处理AI聊天请求 - 用户: {}, 消息数: {}", 
            request.getUserId(), request.getMessages() != null ? request.getMessages().size() : 0);
    }

    /**
     * 验证请求参数
     *
     * @param request 聊天请求
     */
    private void validateRequest(AiChatRequest request) {
        if (request.getMessages() == null || request.getMessages().isEmpty()) {
            throw new IllegalArgumentException("消息列表不能为空");
        }
        
        if (request.getTemperature() != null && (request.getTemperature() < 0 || request.getTemperature() > 2)) {
            throw new IllegalArgumentException("温度参数必须在0-2之间");
        }
        
        if (request.getTopP() != null && (request.getTopP() < 0 || request.getTopP() > 1)) {
            throw new IllegalArgumentException("Top-p参数必须在0-1之间");
        }
        
        if (request.getMaxTokens() != null && request.getMaxTokens() <= 0) {
            throw new IllegalArgumentException("最大token数必须大于0");
        }
    }

    /**
     * 知识库增强
     *
     * @param request 聊天请求
     */
    private void enhanceWithKnowledge(AiChatRequest request) {
        try {
            // 获取最后一条用户消息
            String userMessage = request.getMessages().stream()
                .filter(msg -> "user".equals(msg.getRole()))
                .reduce((first, second) -> second)
                .map(AiChatRequest.AiMessage::getContent)
                .orElse("");
            
            if (StringUtils.hasText(userMessage)) {
                // 执行知识库检索
                List<KnowledgeSearchResultVo> searchResults = knowledgeVectorService.vectorSimilaritySearch(
                    request.getKnowledgeId(),
                    userMessage,
                    request.getModel(),
                    request.getKnowledgeLimit() != null ? request.getKnowledgeLimit() : 5,
                    request.getKnowledgeThreshold() != null ? request.getKnowledgeThreshold() : 0.7
                );
                
                if (!searchResults.isEmpty()) {
                    // 构建知识库上下文
                    StringBuilder contextBuilder = new StringBuilder();
                    contextBuilder.append("以下是相关的知识库信息，请参考这些信息回答用户问题：\n\n");
                    
                    for (int i = 0; i < searchResults.size(); i++) {
                        KnowledgeSearchResultVo result = searchResults.get(i);
                        contextBuilder.append(String.format("[知识%d] %s\n", i + 1, result.getContent()));
                    }
                    
                    contextBuilder.append("\n请基于以上知识库信息回答用户问题。如果知识库中没有相关信息，请明确说明。\n\n");
                    
                    // 在消息列表开头添加系统消息
                    AiChatRequest.AiMessage systemMessage = new AiChatRequest.AiMessage()
                        .setRole("system")
                        .setContent(contextBuilder.toString());
                    
                    List<AiChatRequest.AiMessage> enhancedMessages = new ArrayList<>();
                    enhancedMessages.add(systemMessage);
                    enhancedMessages.addAll(request.getMessages());
                    
                    request.setMessages(enhancedMessages);
                    
                    log.debug("知识库增强完成 - 检索到{}条相关信息", searchResults.size());
                }
            }
            
        } catch (Exception e) {
            log.warn("知识库增强失败，继续使用原始请求", e);
        }
    }

    /**
     * 后处理响应
     *
     * @param response 聊天响应
     * @param request 原始请求
     */
    private void postprocessResponse(AiChatResponse response, AiChatRequest request) {
        // 设置用户信息
        if (response.getExtra() == null) {
            response.setExtra(new java.util.HashMap<>());
        }
        response.getExtra().put("userId", request.getUserId());
        response.getExtra().put("sessionId", request.getSessionId());
        
        // 记录响应日志
        log.debug("后处理AI聊天响应 - 用户: {}, 成功: {}", 
            request.getUserId(), response.getSuccess());
    }

    /**
     * 创建错误响应
     *
     * @param error 错误信息
     * @param request 原始请求
     * @return 错误响应
     */
    private AiChatResponse createErrorResponse(Throwable error, AiChatRequest request) {
        return new AiChatResponse()
            .setSuccess(false)
            .setError(error.getMessage())
            .setErrorCode("CHAT_ERROR")
            .setModel(request.getModel())
            .setCreateTime(java.time.LocalDateTime.now());
    }

    /**
     * 流式回调接口
     */
    public interface StreamCallback {
        /**
         * 接收流式数据
         *
         * @param chunk 数据块
         */
        void onChunk(String chunk);

        /**
         * 流式完成
         *
         * @param response 完整响应
         */
        void onComplete(AiChatResponse response);

        /**
         * 流式错误
         *
         * @param error 错误信息
         */
        void onError(Throwable error);
    }
}